#include <stdio.h>

#include <uv.h>

#include <anb/net/loop.h>
#include <anb/net/server.h>
#include <anb/net/connection_base.h>

#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>

uv_loop_t* loop;

int64_t counter = 0;

void wait_for_a_while(uv_idle_t* handle, int status) {
	counter++;
	if (counter > 10e5) {
		uv_idle_stop(handle);
	}
}

void on_new_connection(uv_stream_t* server, int status) {
	if (status == -1) {
		fprintf(stderr, "failed on_new_connection %d", status);
		return;
	}
	uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof(uv_tcp_t));
	uv_tcp_init(loop, client);
	int ret = uv_accept(server, (uv_stream_t*)client);
	if (ret != 0) {
		uv_close((uv_handle_t*)client, NULL);
		fprintf(stderr, "failed to accept %d", ret);
		return;
	}
    printf("accepted");
	//uv_read_start((uv_stream_t*)client, alloc_buffer, echo_read);
}

void test() {
    loop = uv_loop_new();

	//uv_idle_t idler;
	//uv_idle_init(loop, &idler);
	//uv_idle_start(&idler, wait_for_a_while);

	uv_tcp_t server;
	uv_tcp_init(loop, &server);

	const char* host = "0.0.0.0";
	int port = 7000;
	struct sockaddr_in bind_addr;
	uv_ip4_addr(host, port, &bind_addr);

	printf("listening on %s:%d", host, port);
	uv_tcp_bind(&server, (struct sockaddr*)&bind_addr, 0);
	int res = uv_listen((uv_stream_t*)&server, 128, on_new_connection);
	if (res) {
		fprintf(stderr, "listen error %d\n", res);
		return;
	}

    uv_run(loop, UV_RUN_DEFAULT);
}

void test1() {
	anb::net::loop::ptr loop(new anb::net::loop());

	const char* host = "0.0.0.0";
	int port = 9986;
	struct sockaddr_in bind_addr;
	uv_ip4_addr(host, port, &bind_addr);

	anb::net::server server(loop, NULL);
	server.start(&bind_addr);

	loop->start();
}

class A {
public:
	A() {
		printf("A::A()\n");
	}
	virtual ~A() {
		printf("A::~A()\n");
	}
};

class B : public A {
public:
	B() {
		printf("B::B()\n");
	}
	virtual ~B() {
		printf("B::~B()\n");
	}
};

void test_boost() {
	//A* a = new A();
	//boost::shared_ptr<A> ptr1(a);
	//boost::shared_ptr<A> ptr2(a);
	//boost::weak_ptr<A> ptr(ptr1);
}

int main(int argc, char* argv[]) {
	//test();
	test1();
	//test_boost();
	getchar();
}
